-- show
-- 功能(无需修改): 动作加速系统整合组件
-- 统一管理砍伐、开采、挖掘、采集等动作的加速功能

-- 防止重复加载
if TUNING.DST_LAN_FLAG == nil then
    TUNING.DST_LAN_FLAG = {}
end

if not TUNING.DST_LAN_FLAG.pono_action_acceleration then
    TUNING.DST_LAN_FLAG.pono_action_acceleration = true

    local SPEED_MULT = 2.0  -- 动作加速倍数

    -- 创建timeline加速版本的辅助函数
    local function CreateFastTimeline(original)
        if not original or #original == 0 then return nil end
        local fast = {}
        for i, event in ipairs(original) do
            table.insert(fast, {
                time = event.time / SPEED_MULT,
                fn = event.fn
            })
        end
        return fast
    end

    -- StateGraph强制加速
    local function ForceAccelerateState(sgname, statename)
        AddStategraphPostInit(sgname, function(sg)
            local state = sg.states[statename]
            if not state then return end
            
            -- 保存原始数据
            local orig_timeline = state.timeline
            local orig_timeout = state.timeout
            local orig_ontimeout = state.ontimeout
            local fast_timeline = CreateFastTimeline(orig_timeline)
            
            -- 【关键修复】对于attack状态,设置ontimeout实现连续攻击
            if statename == "attack" and not orig_timeout then
                state.ontimeout = function(inst_inner)
                    -- 【修复】兼容客户端和服务器端
                    local energy_comp = (inst_inner.replica.mod_pono_energy or inst_inner.components.mod_pono_energy)
                    local combat_comp = (inst_inner.replica.combat or inst_inner.components.combat)
                    
                    -- 检查是否是pono且有能量加成
                    local should_continue_attack = inst_inner 
                        and inst_inner.prefab == "pono" 
                        and combat_comp
                        and energy_comp
                    
                    if should_continue_attack then
                        local energy = energy_comp:GetVal() or 0
                        if energy >= 25 and energy <= 175 then
                            -- 重置攻击冷却,允许立即再次攻击（仅服务器端有效）
                            if inst_inner.components.combat then
                                inst_inner.components.combat.lastdoattacktime = 0
                            end
                            
                            -- 【核心】如果还有攻击目标,立即强制进入下一次攻击
                            local target = combat_comp.target
                            if target and target:IsValid() then
                                -- 检查目标是否在攻击范围内
                                local distsq = inst_inner:GetDistanceSqToInst(target)
                                local range = 9  -- 默认攻击范围
                                if combat_comp.CalcAttackRangeSq then
                                    range = combat_comp:CalcAttackRangeSq(target)
                                end
                                
                                if distsq <= range * 1.5 then  -- 稍微放宽范围检查
                                    -- 不返回idle,直接再次进入attack状态
                                    inst_inner.sg:GoToState("attack", target)
                                    return  -- 不调用原始ontimeout,直接返回
                                end
                            end
                        end
                    end
                    
                    -- 调用原始 ontimeout (正常返回idle)
                    if orig_ontimeout then
                        orig_ontimeout(inst_inner)
                    end
                end
            end
            
            -- Hook onenter
            local old_onenter = state.onenter
            state.onenter = function(inst, ...)
                -- 【修复】兼容客户端和服务器端：优先使用replica（客户端），fallback到components（服务器端）
                local energy_comp = (inst.replica.mod_pono_energy or inst.components.mod_pono_energy)
                local energy = energy_comp and energy_comp:GetVal() or 0
                
                local should_boost = inst.prefab == "pono" 
                    and energy_comp
                    and energy >= 25 
                    and energy <= 175
                
                if should_boost then
                    inst.AnimState:SetDeltaTimeMultiplier(SPEED_MULT)
                    
                    -- 应用快速timeline
                    if fast_timeline then
                        state.timeline = fast_timeline
                    end
                    
                    -- 【关键修复】对于attack状态,强制添加timeout
                    if statename == "attack" and not orig_timeout then
                        state.timeout = 0.25  -- 给足时间让攻击判定触发
                    elseif orig_timeout then
                        -- 其他有timeout的状态，正常缩短
                        state.timeout = orig_timeout / SPEED_MULT
                    end
                    
                    -- 【最终方案】对doshortaction/dolongaction，直接在实例上设置定时器强制结束
                    if (statename == "doshortaction" or statename == "dolongaction") and not orig_timeout then
                        if inst.bufferedaction then
                            local action = inst.bufferedaction
                            local action_id = action.action and (action.action.id or action.action) or "unknown"
                            
                            -- 对BUILD动作，0.5秒后强制完成
                            if action_id == "BUILD" or action.action == ACTIONS.BUILD then
                                local build_time = 0.5
                                
                                -- 清理旧的定时器（如果有）
                                if inst._pono_build_task then
                                    inst._pono_build_task:Cancel()
                                    inst._pono_build_task = nil
                                end
                                
                                inst._pono_build_task = inst:DoTaskInTime(build_time, function()
                                    inst._pono_build_task = nil
                                    if inst.sg and inst.sg.currentstate and inst.sg.currentstate.name == statename then
                                        -- 触发StateGraph的timeout逻辑
                                        if inst.sg.currentstate.ontimeout then
                                            inst.sg.currentstate.ontimeout(inst)
                                        else
                                            -- 如果没有ontimeout，直接结束状态
                                            inst.sg:GoToState("idle")
                                        end
                                    end
                                end)
                            -- 对PICK动作，0.3秒后强制完成
                            elseif action_id == "PICK" or action.action == ACTIONS.PICK then
                                local pick_time = 0.3
                                
                                if inst._pono_pick_task then
                                    inst._pono_pick_task:Cancel()
                                    inst._pono_pick_task = nil
                                end
                                
                                inst._pono_pick_task = inst:DoTaskInTime(pick_time, function()
                                    inst._pono_pick_task = nil
                                    if inst.sg and inst.sg.currentstate and inst.sg.currentstate.name == statename then
                                        if inst.sg.currentstate.ontimeout then
                                            inst.sg.currentstate.ontimeout(inst)
                                        else
                                            inst.sg:GoToState("idle")
                                        end
                                    end
                                end)
                            end
                        end
                    end
                else
                    inst.AnimState:SetDeltaTimeMultiplier(1)
                    state.timeline = orig_timeline
                    if orig_timeout then
                        state.timeout = orig_timeout
                    end
                end
                
                if old_onenter then 
                    return old_onenter(inst, ...) 
                end
            end
            
            -- Hook onexit
            local old_onexit = state.onexit
            state.onexit = function(inst, ...)
                inst.AnimState:SetDeltaTimeMultiplier(1)
                state.timeline = orig_timeline
                if orig_timeout then
                    state.timeout = orig_timeout
                elseif statename == "attack" then
                    -- 恢复attack状态的timeout为nil (原本没有)
                    state.timeout = nil
                end
                
                -- 清理加速定时器
                if inst._pono_build_task then
                    inst._pono_build_task:Cancel()
                    inst._pono_build_task = nil
                end
                if inst._pono_pick_task then
                    inst._pono_pick_task:Cancel()
                    inst._pono_pick_task = nil
                end
                
                if old_onexit then 
                    return old_onexit(inst, ...) 
                end
            end
        end)
    end

    -- 所有需要加速的状态
    local states_to_accelerate = {
        "chop",           -- 砍伐
        "mine",           -- 开采
        "dig",            -- 挖掘
        "doshortaction",  -- 短动作：采集、快速制作等
        "dolongaction",   -- 长动作：建造、长时间制作等
        "hammer",         -- 敲击建筑
        "attack",         -- 攻击
        "hit",            -- 命中
    }
    
    -- Hook所有状态（主机+客户端）
    for _, statename in ipairs(states_to_accelerate) do
        ForceAccelerateState("wilson", statename)
        ForceAccelerateState("wilson_client", statename)
    end

    -- BUILD动作加速：直接修改ACTIONS.BUILD的time
    if ACTIONS and ACTIONS.BUILD then
        local original_build_time = ACTIONS.BUILD.time or 1
        ACTIONS.BUILD.time = function(inst)
            -- 【修复】兼容客户端和服务器端
            local energy_comp = (inst.replica.mod_pono_energy or inst.components.mod_pono_energy)
            if inst.prefab == "pono" and energy_comp then
                local energy = energy_comp:GetVal() or 0
                if energy >= 25 and energy <= 175 then
                    return original_build_time * 0.2  -- 5倍速
                end
            end
            return original_build_time
        end
    end

    -- 【调试】添加全局函数方便测试能量系统
    if not rawget(GLOBAL, "PonoSetEnergy") then
        rawset(GLOBAL, "PonoSetEnergy", function(val)
            local player = GLOBAL.ThePlayer
            if player and player.components and player.components.mod_pono_energy then
                player.components.mod_pono_energy:SetVal(val)
            end
        end)

        rawset(GLOBAL, "PonoGetEnergy", function()
            local player = GLOBAL.ThePlayer
            if player and player.components and player.components.mod_pono_energy then
                local val = player.components.mod_pono_energy:GetVal()
                return val
            end
            return nil
        end)
    end

    -- 【修复】右键装备功能
    AddPrefabPostInit("pono", function(inst)
        inst:DoTaskInTime(0.1, function()
            if inst.components.playeractionpicker then
                -- 保存原始右键动作函数
                local old_GetRightClickActions = inst.components.playeractionpicker.GetRightClickActions
                
                -- 重写右键动作函数，确保装备动作正常工作
                inst.components.playeractionpicker.GetRightClickActions = function(self, pos, target, spellbook)
                    local actions = old_GetRightClickActions(self, pos, target, spellbook) or {}
                    
                    -- 检查是否是可装备物品且在我的物品栏中
                    if target and target.components.equippable and target.components.inventoryitem then
                        local owner = target.components.inventoryitem.owner
                        if owner == inst then  -- 确保物品在我的物品栏中
                            -- 检查是否已经有装备动作
                            local has_equip_action = false
                            for _, action in ipairs(actions) do
                                if action.action == ACTIONS.EQUIP then
                                    has_equip_action = true
                                    break
                                end
                            end
                            
                            -- 如果没有装备动作但可以装备，手动添加装备动作
                            if not has_equip_action and target.components.equippable:CanEquip(inst) then
                                local equip_action = GLOBAL.BufferedAction(inst, target, ACTIONS.EQUIP)
                                table.insert(actions, equip_action)
                            end
                        end
                    end
                    
                    return actions
                end
            end
        end)
    end)

end